﻿/*
    Parker for Kaixin001.com 

    Copyright (C) 2008, TurboZV, turbozv@gmail.com, http://www.turbozv.com/

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    *KEEP THIS HEADER INFORMATION*
*/

using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Net.Json;
using System.Text;
using Helper;
using System.Collections.Generic;

namespace Parker
{
    public class CarInfo
    {
        public int Id;
        public int Profit;
        public int ParkingMinutes; // 停车时间
        public int ParkUserId;
        public bool IsWandering; // 被贴牌或新买的车，在路上跑
        public string CarName;
        public string ParkUserName;
    }

    public class UserInfo
    {
        public int Id;
        public string Name;
        public bool Full;
        public bool Online;
    }

    public class Parker : IRunner
    {
        #region IRunner Members

        public void LoadConfig(string filename)
        {
            _configData = ConfigHelper.ReadConfigData(filename);
        }

        public bool Run(GlobalConfigData globalConfigData)
        {
            if (_configData == null || globalConfigData == null)
            {
                return false;
            }

            _hh.SetConfig(globalConfigData);

            _parkFailed = 0;

            if (!Logon(globalConfigData))
            {
                return false;
            }

            string content = GetAppHomePage();
            TraceLog.Print("自动获取AccCode: ");
            _accCode = "acc=" + ScriptHelper.GetAccCode_Re(content);
            TraceLog.PrintLn(_accCode);

            TraceLog.Print("自动获取VerifyCode: ");
            _verifyCode = ContentHelper.GetVerifyCode(content);
            TraceLog.PrintLn(_verifyCode);

            ReadCarInfo(content);

            ReadFriendList(content);

            ShowCarInfo();

            ParkCars();

            //DoPost();

            //CallPolice();

            //BuyNewCarAndUpgrade();

            Logout();

            return (_parkFailed == 0);
        }
        #endregion

        private string GetAppHomePage()
        {
            string content = _hh.Get("http://www.kaixin001.com/app/app.php?aid=1040");
            if (content.IndexOf("<title>添加组件 - 开心网</title>") != -1)
            {
                // 添加组件
                string postData = "aid=1040&isinstall=1";
                content = _hh.Post("http://www.kaixin001.com/app/install.php", postData);
            }

            return content;
        }

        // 把买车升级的功能拿出来作为一个方法，这样和其他功能同级  // by hook.hu@gmail.com 2008-09-23
        private void BuyNewCarAndUpgrade()
        {
            /*  添加自动买车/升级车/升级免费车位功能
             *  by xzsong.seu@gmail.com, 2008-09-20
             */
            CarAutoHelper carAutoHelper = new CarAutoHelper(_hh, _configData, _verifyCode);
            Collection<int> newCarIdList = new Collection<int>();
            // 买了新车，准备停放
            if (carAutoHelper.AutoBuyAndUpgrade(_cash, _carInfoList, _seatList))   // 买车/升级操作成功
            {
                string content = _hh.Get("http://www.kaixin001.com/app/app.php?aid=1040");
                ReadCarInfo(content);    // 重新刷一次页面，读一次车位满否的信息
                ReadFriendList(content);

                // 用户设置要求停车，才停新车。否则就让他在路上跑
                if (_configData.DoParking)
                {
                    foreach (CarInfo car in _carInfoList)
                    {
                        if (car.IsWandering)  // 停放没车位的车
                        {
                            TraceLog.Print("#_:{0} ", car.CarName);
                            if (!ParkTheCar(car))
                                TraceLog.Error("新买的 {0} 还在路上跑，请注意！", car.CarName);
                        }
                    }
                }
                else
                {
                    TraceLog.PrintLn("用户设定不停车，新买的车请自行处理");
                }
            }
        }

        /* 报警功能 by lu.xiandong@gmail.com, 2008-09-20
         * 
         * 1.先得到每一个好友的车信息。
         * 2.得车所在的用户id
         * 3.得到此用户所有车位信息
         * 4.遍历报警
         */
        private void CallPolice()
        {
            if (_configData.DoCall == false)
            {
                return;
            }
            foreach (UserInfo user in _friendList)
            {
                int pos;
                string getParkUid = _hh.Post("http://www.kaixin001.com/parking/usercar.php", "verify=" + _verifyCode + "&puid=" + user.Id);
                string jsonText = ContentHelper.GetMidString(getParkUid, "v_userdata = ", "\n", out pos);

                JsonTextParser parser = new JsonTextParser();
                JsonObject obj = parser.Parse(jsonText);
                JsonObjectCollection data = obj as JsonObjectCollection;
                JsonArrayCollection cars = data["car"] as JsonArrayCollection;
                if (_configData.NoCallList.Contains(user.Id))
                {
                    TraceLog.PrintLn("(不举报用户 {0} {1})", user.Name, user.Id);
                    continue;
                }

                if (IsNeighbor(user.Id))
                {
                    continue;
                }
                TraceLog.PrintLn("举报好友 {0}\n", user.Name);
                int i = 0;
                foreach (JsonObjectCollection car in cars)
                {

                    i++;
                    int parkUid = JsonHelper.GetIntegerValue(car["park_uid"]);
                    string parkName = JsonHelper.GetStringValue(car["park_real_name"]);
                    string carName = JsonHelper.GetStringValue(car["car_name"]);

                    //开始得到车位
                    if (parkUid <= 0 || IsNeighbor(parkUid))
                    {
                        TraceLog.PrintLn("->#{2} {0} 把[{1}]停邻居家了,或许是没车位了\n", user.Name, carName, i);
                        continue;
                    }
                    TraceLog.PrintLn("->#{3} {0} 把[{2}]停在[{1}]的车位了,举报！！\n", user.Name, parkName, carName, i);

                    JsonTextParser parser_user = new JsonTextParser();
                    string c = _hh.Post("http://www.kaixin001.com/parking/user.php", "verify=" + _verifyCode + "&puid=" + parkUid);
                    JsonObject user_data = parser_user.Parse(c);
                    JsonObjectCollection user_data_table = user_data as JsonObjectCollection;
                    JsonArrayCollection seatOthers = user_data_table["parking"] as JsonArrayCollection;
                    foreach (JsonObjectCollection seat in seatOthers)  // 举报此人每个车位上的车
                    {
                        int parkId = JsonHelper.GetIntegerValue(seat["parkid"]);
                        int car_uid = JsonHelper.GetIntegerValue(seat["car_uid"]);

                        if (car_uid == user.Id)
                        {
                            DoCall(parkUid, parkId);
                        }
                    }
                }
            }
        }


        private void Logout()
        {
            TraceLog.PrintLn("当前现金变为 {0} 元", _cash);
            TraceLog.Print("Logout: ");
            //_hh.Get("http://www.kaixin001.com/login/logout.php");
            TraceLog.PrintLn("Ok!\n");
        }

        // 分离出来的函数。获取当前用户中可停车的列表   // by hook.hu@gmail.com 2008-09-23 16:40
        private Collection<int> GetValidParkList()
        {
            Collection<int> parkList = new Collection<int>();

            foreach (int id in _parkList)
            {
                if (id <= 0)
                {
                    continue;
                }
                UserInfo user = GetUserInfo(id);
                if (null == user || user.Full)  // 这个用户不能停
                {
                    continue;
                }
                parkList.Add(user.Id);
            }
            return parkList;
        }

        private void ParkCars()
        {
            _parkedPosList.Clear();
            if (!_configData.DoParking)
            {
                return;
            }

            TraceLog.PrintLn("开始停车:");
            int no = 0;
            foreach (CarInfo car in _carInfoList)
            {
                if (car.ParkingMinutes < 15 && !car.IsWandering)
                {
                    TraceLog.PrintLn(" #{0}:{1} [忽略](不足15分钟)", ++no, car.CarName, car.Profit);
                    continue;
                }
                else
                {
                    TraceLog.Print(" #{0}:{1} ", ++no, car.CarName);
                    ParkTheCar(car);
                }
            }
        }

        /// <summary>
        /// 处理某一辆车的策略
        /// </summary>
        /// <param name="car">要处理的车</param>
        /// <returns>是否成功完成（设定不挪的也算成功）</returns>
        private bool ParkTheCar(CarInfo car)
        {
            Collection<int> validParkList = GetValidParkList();
            if (validParkList.Count <= 0)
            {
                TraceLog.Error("车位都满了，无法停车！");
                return false;
            }

            if (car.ParkUserId == _configData.MasterId)  // 停在主人家，不动
            {
                TraceLog.PrintLn(" 主人家，不挪动");
                return true;
            }

            if (TryParkTheCar(car, validParkList))  // 尝试停车，成功
            {
                _cash += car.Profit;   // 车成功停过去，现金就增加了

                // 车停过去，之前停车的车位就空出来了
                UserInfo user = GetUserInfo(car.ParkUserId);
                if (null != user)
                {
                    user.Full = false;
                }
                TraceLog.PrintLn("Ok!");
                return true;
            }
            else // 试图停车失败
            {
                TraceLog.Error("ERROR! 请注意！");
                _parkFailed++;
                return false;
            }
        }

        private UserInfo GetUserInfo(int id)
        {
            if (id <= 0)
            {
                return null;
            }

            foreach (UserInfo user in _friendList)
            {
                if (user.Id == id)
                {
                    return user;
                }
            }

            // read from internet
            string postData = "verify=" + _verifyCode + "&puid=" + id.ToString() + "&_=";
            string url;

            if (IsNeighbor(id))
            {
                url = "http://www.kaixin001.com/parking/neighbor.php";
            }
            else
            {
                url = "http://www.kaixin001.com/parking/user.php";
            }
            string content = _hh.Post(url, postData);

            JsonTextParser parser = new JsonTextParser();
            JsonObject obj = parser.Parse(content);
            JsonObjectCollection data = obj as JsonObjectCollection;
            JsonObjectCollection theUser = data["user"] as JsonObjectCollection;
            JsonArrayCollection parking = data["parking"] as JsonArrayCollection;
            UserInfo newUser = new UserInfo();
            newUser.Id = id;
            newUser.Name = JsonHelper.GetStringValue(theUser["real_name"]);
            newUser.Full = true;
            foreach (JsonObjectCollection seat in parking)
            {
                int carid = JsonHelper.GetIntegerValue(seat["carid"]);
                int parkid = JsonHelper.GetIntegerValue(seat["parkid"]);
                if (CanParkHere(carid, parkid))
                {
                    newUser.Full = false;
                    break;
                }
            }
            return newUser;
        }

        private string GetUserName(int id)
        {
            foreach (UserInfo user in _friendList)
            {
                if (user.Id == id)
                {
                    return user.Name;
                }
            }

            return id.ToString();
        }

        private void ReadCarInfo(string content)
        {
            int pos;
            string jsonText = ContentHelper.GetMidString(content, "v_userdata = ", "\n", out pos);
            if (null == jsonText)
            {
                TraceLog.Error("未读到用户数据，请务必手工登陆停一次车后，再使用！");
                return;
            }
            JsonTextParser parser = new JsonTextParser();
            JsonObject obj = parser.Parse(jsonText);
            JsonObjectCollection data = obj as JsonObjectCollection;
            JsonObjectCollection user = data["user"] as JsonObjectCollection;
            _seatList = data["parking"] as JsonArrayCollection;
            JsonObjectCollection config = data["config"] as JsonObjectCollection;
            _seatMoneyMinute = JsonHelper.GetIntegerValue(config["money_minute"]);
            JsonArrayCollection carList = data["car"] as JsonArrayCollection;

            int id = JsonHelper.GetIntegerValue(user["uid"]);
            string name = JsonHelper.GetStringValue(user["real_name"]);

            _cash = JsonHelper.GetIntegerValue(user["cash"]);

            Collection<CarInfo> carParked = new Collection<CarInfo>();  // 已停好的车
            Collection<CarInfo> carWandering = new Collection<CarInfo>();  // 在路上跑的车
            int carMoney = 0;
            foreach (JsonObjectCollection car in carList)
            {
                CarInfo carInfo = new CarInfo();
                carInfo.Id = JsonHelper.GetIntegerValue(car["carid"]);
                carInfo.Profit = JsonHelper.GetIntegerValue(car["park_profit"]);
                carInfo.ParkingMinutes = JsonHelper.GetIntegerValue(car["park_profit"]) / JsonHelper.GetIntegerValue(car["park_moneyminute"]);
                carInfo.ParkUserId = JsonHelper.GetIntegerValue(car["park_uid"]);
                carInfo.CarName = JsonHelper.GetStringValue(car["car_name"]);
                carInfo.ParkUserName = JsonHelper.GetStringValue(car["park_real_name"]);
                string parkMoneyMinute = JsonHelper.GetStringValue(car["park_moneyminute"]);
                carInfo.IsWandering = (null == parkMoneyMinute);

                carMoney += JsonHelper.GetIntegerValue(car["price"]);

                if (carInfo.IsWandering)
                {
                    carWandering.Add(carInfo);
                }
                else
                {
                    carParked.Add(carInfo);
                }
            }

            TraceLog.PrintLn("{0}({1}) 现金:{2} 车价:{3} 总价:{4}", name, id, _cash, carMoney, _cash + carMoney);

            // 停车顺序： profit高的>profit低的>被贴条的
            for (int i = 0; i < carParked.Count; i++)
            {
                for (int j = i + 1; j < carParked.Count; j++)
                {
                    if (carParked[i].Profit < carParked[j].Profit)
                    {
                        CarInfo tmp = carParked[i];
                        carParked[i] = carParked[j];
                        carParked[j] = tmp;
                    }
                }
            }

            _carInfoList.Clear();
            foreach (CarInfo car in carParked)
            {
                _carInfoList.Add(car);
            }
            foreach (CarInfo car in carWandering)
            {
                _carInfoList.Add(car);
            }
        }

        /// <summary>
        /// 自动贴条处理
        /// </summary>
        private void DoPost()
        {
            if (!_configData.DoPost)
            {
                return;
            }
            TraceLog.PrintLn("开始贴条:");
            int no = 0;
            foreach (JsonObjectCollection seat in _seatList)
            {
                int carid = JsonHelper.GetIntegerValue(seat["carid"]);
                if (carid <= 0)
                {
                    TraceLog.PrintLn(" #{0}: 空闲", ++no);
                    continue;
                }

                string userName = JsonHelper.GetStringValue(seat["car_real_name"]);
                string carName = JsonHelper.GetStringValue(seat["car_name"]);
                int profit = JsonHelper.GetIntegerValue(seat["car_profit"]);
                int parkId = JsonHelper.GetIntegerValue(seat["parkid"]);
                int car_uid = JsonHelper.GetIntegerValue(seat["car_uid"]);
                TraceLog.Print(" #{0}: {1} 的 {2} (收入{3}元) ", ++no, userName, carName, profit);

                if (_seatMoneyMinute <= 0)
                {
                    _seatMoneyMinute = 10;
                }
                int money_minute = profit / _seatMoneyMinute;
                if (money_minute < 15 && !_configData.DoPostLess15)
                {
                    TraceLog.PrintLn("不足15分钟，不贴条");
                    continue;
                }

                if (_configData.NoPostList.Contains(car_uid))
                {
                    TraceLog.PrintLn("(不贴条白名单用户)");
                    continue;
                }

                // notemper2x@gmail.com 增加于 2008-09-26
                // 针对不同用户配置不同参数
                int configProfit = 0;
                if (!_configData.PostList.TryGetValue(car_uid, out configProfit))
                {
                    if (!_configData.PostList.TryGetValue(-1, out configProfit))
                    {
                        configProfit = 0;
                    }
                }
                if (configProfit == -1)
                {
                    TraceLog.PrintLn("(不贴)");
                    continue;
                }
                else if (profit < configProfit)
                {
                    TraceLog.PrintLn("(达到{0}元时才贴)", configProfit);
                    continue;
                }

                // 贴条
                if (DoPostById(parkId))
                {
                    _cash += profit;    // 贴条后现金增加
                }
            }
        }

        private bool DoPostById(int parkId)
        {
            string postData = string.Format("{0}&verify={1}&parkid={2}&_=",
                _accCode,  //开心网防外挂校验参数……
                _verifyCode, parkId);
            string content = _hh.Post("http://www.kaixin001.com/parking/post.php", postData);

            JsonTextParser parser = new JsonTextParser();
            JsonObject obj = parser.Parse(content);
            JsonObjectCollection data = obj as JsonObjectCollection;
            string result = JsonHelper.GetStringValue(data["error"]);

            if (result.Contains("他的捷达"))  //贴太快就出现这个
            {
                TraceLog.PrintLn("贴条失败!");
                return false;
            }
            TraceLog.PrintLn(result);
            return true;
        }

        private void DoCall(int parkUId, int parkId)
        {
            string postData = string.Format("{0}&verify={1}&park_uid={2}&parkid={3}",
                _accCode,  //开心网防外挂校验参数……
                _verifyCode, parkUId, parkId);
            string content = _hh.Post("http://www.kaixin001.com/parking/call.php", postData);
            // TraceLog.PrintLn("报警: "+parkUId+" "+parkId);
        }

        private void ShowCarInfo()
        {
            TraceLog.PrintLn("停车信息:");
            for (int i = 0; i < _carInfoList.Count; i++)
            {
                if (_carInfoList[i].IsWandering)
                {
                    TraceLog.PrintLn(" #{0}:{1}, 目前没有车位",
                        i + 1, _carInfoList[i].CarName);
                }
                else
                {
                    TraceLog.PrintLn(" #{0}:{1}, 目前停在 {2}{3} 的私家车位 收入{4}元",
                        i + 1, _carInfoList[i].CarName, _carInfoList[i].ParkUserName,
                        (_carInfoList[i].ParkUserId == _configData.MasterId) ? "(主人家)" : "", _carInfoList[i].Profit);
                }
            }
        }

        private void ReadFriendList(string content)
        {
            TraceLog.PrintLn("读取好友信息:");
            int pos;
            string jsonText = ContentHelper.GetMidString(content, "v_frienddata = ", "\n", out pos);
            if (null == jsonText)
            {
                TraceLog.Error("未读到用户数据，请务必手工登陆停一次车后，再使用！");
                return;
            }
            JsonTextParser parser = new JsonTextParser();
            JsonObject obj = parser.Parse(jsonText);
            JsonArrayCollection data = obj as JsonArrayCollection;
            int no = 0;
            _friendList.Clear();
            Collection<int> friendIdList = new Collection<int>();
            foreach (JsonObjectCollection user in data)
            {
                UserInfo friend = new UserInfo();
                friend.Id = JsonHelper.GetIntegerValue(user["uid"]);
                friend.Full = (JsonHelper.GetStringValue(user["full"]) != "0");
                friend.Name = JsonHelper.GetStringValue(user["real_name"]);
                friend.Online = (JsonHelper.GetIntegerValue(user["online"]) == 1);
                //string friendType = IsNeighbor(JsonHelper.GetIntegerValue(user["neighbor"])) ? "邻居" : "好友";
                TraceLog.PrintLn(string.Format(" #{0}: {1}({2}) {3}", ++no, friend.Name, friend.Id, friend.Full ? "车位满" : ""));

                _friendList.Add(friend);
                friendIdList.Add(friend.Id);
            }

            // Generate park list 
            _parkList.Clear();
            // 1. 主人ID
            if (-1 != _configData.MasterId && friendIdList.Contains(_configData.MasterId))
            {
                _parkList.Add(_configData.MasterId);
            }

            // 2. 停车白名单
            foreach (int id in _configData.WhiteList)
            {
                if (friendIdList.Contains(id))
                {
                    if (!_parkList.Contains(id))
                    {
                        _parkList.Add(id);
                    }
                }
            }

            // 2. 普通朋友
            foreach (int id in friendIdList)
            {
                if (!_configData.BlackList.Contains(id) && !_configData.NoParkingList.Contains(id))
                {
                    if (!_parkList.Contains(id))
                    {
                        _parkList.Add(id);
                    }
                }
            }

            // 3. 可能有的空位
            foreach (CarInfo car in _carInfoList)
            {
                if (car.ParkUserId > 0 && !_parkList.Contains(car.ParkUserId) && !_configData.BlackList.Contains(car.ParkUserId) && !_configData.NoParkingList.Contains(car.ParkUserId))
                {
                    _parkList.Add(car.ParkUserId);
                }
            }

            // 3. 黑名单
            foreach (int id in _configData.BlackList)
            {
                if (friendIdList.Contains(id) || IsNeighbor(id))
                {
                    if (!_parkList.Contains(id))
                    {
                        _parkList.Add(id);
                    }
                }
            }

            if (_parkList.Contains(2))
            {
                _friendList.Add(GetUserInfo(2));
            }
            if (_parkList.Contains(1))
            {
                _friendList.Add(GetUserInfo(1));
            }
        }

        /// <summary>
        /// Logon to kaixin.com
        /// </summary>
        /// <returns></returns>
        private bool Logon(GlobalConfigData globalConfigData)
        {
            // 1. Logon
            TraceLog.Print("Login as [{0}]: ", _configData.Email);
            string content = _hh.Post("http://www.kaixin001.com/login/login.php", "url=%2F&email=" + HttpHelper.EncodePostData(_configData.Email) + "&password=" + HttpHelper.EncodePostData(_configData.Password));

            if (content.IndexOf("<title>我的首页 - 开心网</title>") != -1)
            {
                TraceLog.PrintLn("Ok!");
                return true;
            }
            else
            {
                TraceLog.Error("Failed!");
                return false;
            }
        }

        /// <summary>
        /// 尝试在有空位用户集合 parkList 中停某一辆车
        /// </summary>
        /// <param name="car">要停的车</param>
        /// <param name="parkList">要尝试的用户ID列表</param>
        /// <returns>是否成功挪动了车</returns>
        private bool TryParkTheCar(CarInfo car, Collection<int> parkList)
        {
            foreach (int id in parkList)
            {
                if (car.ParkUserId == id) //本来就停在这车位，不必尝试了
                {
                    continue;
                }
                if (_configData.NoParkingList.Contains(id))  // 不停车名单中的直接跳过
                {
                    TraceLog.PrintLn("不停车名单，不能停！");
                    continue;
                }

                TraceLog.Print("=>{0}({1})", GetUserName(id), id);

                //TraceLog.PrintLn("Find seats in friend: " + id);
                string postData = string.Format("verify={0}&puid={1}&_=", _verifyCode, id);
                string content = string.Empty;
                if (IsNeighbor(id))
                {
                    //邻居
                    content = _hh.Post("http://www.kaixin001.com/parking/neighbor.php", postData);
                }
                else
                {
                    // 朋友
                    content = _hh.Post("http://www.kaixin001.com/parking/user.php", postData);
                }

                try
                {
                    JsonTextParser parser = new JsonTextParser();
                    JsonObject obj = parser.Parse(content);
                    JsonObjectCollection data = obj as JsonObjectCollection;
                    JsonArrayCollection parking = data["parking"] as JsonArrayCollection;

                    JsonObjectCollection user = data["user"] as JsonObjectCollection;
                    string name = JsonHelper.GetStringValue(user["real_name"]);

                    int seatNo = 1;
                    ParkCarResult tryParkResult = ParkCarResult.PARK_FAILED_OTHER;
                    foreach (JsonObjectCollection seat in parking)
                    {
                        int carId = JsonHelper.GetIntegerValue(seat["carid"]);
                        int parkId = JsonHelper.GetIntegerValue(seat["parkid"]);
                        // 车位空 && 不是免费停车位
                        if (CanParkHere(carId, parkId))
                        {
                            string parkingPostData = string.Format("{0}&verify={1}&park_uid={2}&parkid={3}&carid={4}&neighbor={5}&first_fee_parking=0&_=",
                                _accCode,  //开心网防外挂校验参数……
                                _verifyCode, id, parkId, car.Id, IsNeighbor(id) ? "1" : "0");
                            tryParkResult = SendParkCarRequest(parkingPostData, id);
                            if (tryParkResult == ParkCarResult.PARK_SUCCESS)
                            {
                                string parkPair = string.Format("{0}#{1}", id, seatNo);
                                if (_parkedPosList.Contains(parkPair))
                                {
                                    TraceLog.PrintLn(" {0} 位置已停成功过。肯定被开心ban了", name + "#" + seatNo);
                                    return false;
                                }
                                else
                                {
                                    TraceLog.Print("车位=>{0}(#{1}) ", name, seatNo);
                                    _parkedPosList.Add(parkPair);  //登记此车位已停过
                                    return true;
                                }
                            }
                            else if (tryParkResult == ParkCarResult.PARK_INVALID_USER)  // 其他车位也不用试了，这人就是不让停
                            {
                                break;
                            }
                        }
                        seatNo++;
                    }

                    if (tryParkResult != ParkCarResult.PARK_INVALID_USER)  // 如果这人只是不让这辆车停，车位不一定满
                    {
                        // 否则4个车位都不能停，说明车位满了
                        UserInfo u = GetUserInfo(id);
                        if (null != u)
                        {
                            u.Full = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    TraceLog.Error(e.Message);
                }
            }

            TraceLog.Print(" 未找到车位！");
            return false;
        }

        // 停车结果，用于分辨试图停车所遇到的各种情况 by hook.hu@gmail.com, 2008.9.22
        enum ParkCarResult
        {
            PARK_SUCCESS = 0,           // 成功停车
            PARK_INVALID_USER = 1,      // 此人所有车位不让停。例如上次停那里被他或者警察贴过条，不让重复停
            PARK_POSITION_TAKEN = 2,    // 当前试的这个车位满了
            PARK_FAILED_OTHER = 99,     // 其他情况，总之停车就是失败了
        };

        private ParkCarResult SendParkCarRequest(string postData, int id)
        {
            try
            {
                string content = _hh.Post("http://www.kaixin001.com/parking/park.php", postData);
                JsonTextParser parser = new JsonTextParser();
                JsonObject obj = parser.Parse(content);
                JsonObjectCollection data = obj as JsonObjectCollection;

                TraceLog.Print(JsonHelper.GetStringValue(data["error"]));
                int errno = JsonHelper.GetIntegerValue(data["errno"]);
                if (errno == 0)
                {
                    return ParkCarResult.PARK_SUCCESS;
                }
                else if (errno == 6)    // 开心定义的错误代码，6 表示“不能停在同一个人车位两次”
                {
                    return ParkCarResult.PARK_INVALID_USER;
                }
                else
                {
                    return ParkCarResult.PARK_POSITION_TAKEN;  //todo: 还没来得及分析各种错误代码。姑且认为其他情况都是车位被占用
                }
            }
            catch (Exception e)
            {
                TraceLog.Error(e.Message);
                Console.WriteLine(e.StackTrace);
                return ParkCarResult.PARK_FAILED_OTHER;
            }
        }

        /// <summary>
        /// If we can park here
        /// </summary>
        private bool CanParkHere(int carId, int parkId)
        {
            // 免费停车位判断 http://pic.kaixin001.com/js/parking-2.js
            // var v_park_free = (v_parkid >> 16) & 0xff;
            // v_mycar += (v_park_free ? '免费' : '私家') + '车位</a>';
            if ((carId == 0 || carId == -1) && ((parkId >> 16) & 0xff) == 0)
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// All neighbor ID == 1 or 2
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private bool IsNeighbor(int id)
        {
            return (id == 2 || id == 1);
        }

        #region Member Fields
        private string _verifyCode;
        private string _accCode;
        private int _parkFailed;

        private HttpHelper _hh = new HttpHelper();  // HTTP辅助类
        private UserConfigData _configData;  // 用户设定

        private int _cash;  // 现金
        private int _seatMoneyMinute = 10;  // 我的车位每分钟多少钱
        private Collection<CarInfo> _carInfoList = new Collection<CarInfo>();  // 所有车的信息
        private Collection<int> _parkList = new Collection<int>();   // 所有车位列表
        private Collection<UserInfo> _friendList = new Collection<UserInfo>();  // 好友信息列表
        private JsonArrayCollection _seatList;  // 我自己的车位信息
        private Collection<string> _parkedPosList = new Collection<string>();  //已停过的车位记录
        #endregion
    }
}
